<template>
  <div class="markdown-viewer">
    <!-- 展开/收起按钮 -->
    <div class="flex items-center justify-between p-4 bg-gray-50 border border-gray-200 rounded-lg cursor-pointer hover:bg-gray-100 transition-colors"
         @click="toggleExpanded">
      <div class="flex items-center space-x-3">
        <span class="text-lg">📚</span>
        <h4 class="text-lg font-semibold text-gray-800">{{ title }}</h4>
      </div>
      <div class="flex items-center space-x-2">
        <span class="text-sm text-gray-500">{{ isExpanded ? '收起' : '展开' }}</span>
        <svg class="w-5 h-5 text-gray-500 transition-transform duration-200"
             :class="{ 'rotate-180': isExpanded }"
             fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M19 9l-7 7-7-7"></path>
        </svg>
      </div>
    </div>

    <!-- 展开的内容区域 -->
    <div v-if="isExpanded" class="mt-4 border border-gray-200 rounded-lg overflow-hidden bg-white">
      <!-- 加载状态 -->
      <div v-if="loading" class="flex items-center justify-center p-8">
        <div class="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-500"></div>
        <span class="ml-3 text-gray-600">加载中...</span>
      </div>

      <!-- 错误状态 -->
      <div v-else-if="error" class="p-6 text-center">
        <div class="text-red-500 mb-2">❌ 加载失败</div>
        <p class="text-gray-600 text-sm">{{ error }}</p>
        <button @click="loadMarkdown" class="mt-3 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 transition-colors">
          重新加载
        </button>
      </div>

      <!-- 内容区域 -->
      <div v-else class="flex h-[700px]">
        <!-- 左侧目录 -->
        <div class="w-1/3 border-r border-gray-200 bg-gray-50 overflow-y-auto">
          <div class="p-4">
            <h5 class="font-semibold text-gray-800 mb-3 flex items-center">
              <span class="mr-2">📋</span>
              目录
            </h5>
            <nav class="space-y-1">
              <div v-for="(heading, index) in tableOfContents" :key="index"
                   class="cursor-pointer hover:bg-gray-200 rounded px-2 py-1 transition-colors"
                   :class="{
                     'ml-0': heading.level === 1,
                     'ml-4': heading.level === 2,
                     'ml-8': heading.level === 3,
                     'ml-12': heading.level === 4,
                     'bg-blue-100 text-blue-800': activeHeading === heading.id
                   }"
                   @click="scrollToHeading(heading.id)">
                <span class="text-sm" :class="{
                  'font-semibold': heading.level <= 2,
                  'font-medium': heading.level === 3,
                  'font-normal': heading.level >= 4
                }">{{ heading.text }}</span>
              </div>
            </nav>
          </div>
        </div>

        <!-- 右侧内容 -->
        <div class="flex-1 overflow-y-auto">
          <div class="p-6 prose prose-sm max-w-none" 
               ref="contentRef"
               @scroll="handleScroll"
               v-html="renderedHtml">
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, onMounted, nextTick } from 'vue'
import { marked } from 'marked'

// Props
const props = defineProps({
  filePath: {
    type: String,
    required: true
  },
  title: {
    type: String,
    default: 'Markdown 文档'
  }
})

// 响应式数据
const isExpanded = ref(false)
const loading = ref(false)
const error = ref('')
const markdownContent = ref('')
const contentRef = ref<HTMLElement | null>(null)
const activeHeading = ref('')

// 渲染的 HTML 内容
const renderedHtml = ref('')

// 渲染 Markdown 内容的函数
const renderMarkdown = async () => {
  if (!markdownContent.value) {
    renderedHtml.value = ''
    return
  }
  
  try {
    // 配置 marked
    marked.setOptions({
      breaks: true,
      gfm: true
    })
    
    const html = await marked(markdownContent.value)
    
    // 手动处理代码块高亮
    const highlightedHtml = html.replace(
      /<pre><code class="language-(\w+)">(.*?)<\/code><\/pre>/gs,
      (match, lang, code) => {
        return `<pre class="bg-gray-100 p-3 rounded overflow-x-auto"><code class="language-${lang}">${code}</code></pre>`
      }
    )
    
    // 生成目录并修改HTML内容
    const { toc, modifiedHtml } = generateTableOfContents(highlightedHtml)
    tableOfContents.value = toc
    renderedHtml.value = modifiedHtml
  } catch (err) {
    console.error('Markdown 渲染错误:', err)
    renderedHtml.value = '<p class="text-red-500">Markdown 渲染失败</p>'
  }
}

// 生成目录的函数
const generateTableOfContents = (htmlContent: string) => {
  const parser = new DOMParser()
  const doc = parser.parseFromString(htmlContent, 'text/html')
  const headings = doc.querySelectorAll('h1, h2, h3, h4, h5, h6')

  const toc: Array<{ id: string, text: string, level: number }> = []

  headings.forEach((heading, index) => {
    const level = parseInt(heading.tagName.charAt(1))
    const text = heading.textContent?.trim() || ''
    const id = `heading-${index}`

    // 为标题添加 ID
    heading.id = id

    if (text) {
      toc.push({ id, text, level })
    }
  })

  return { toc, modifiedHtml: doc.body.innerHTML }
}

// 目录数据
const tableOfContents = ref<Array<{ id: string, text: string, level: number }>>([])

// 方法
const toggleExpanded = async () => {
  isExpanded.value = !isExpanded.value
  
  if (isExpanded.value && !markdownContent.value) {
    await loadMarkdown()
  }
}

const loadMarkdown = async () => {
  loading.value = true
  error.value = ''
  
  try {
    const response = await fetch(props.filePath)
    if (!response.ok) {
      throw new Error(`HTTP ${response.status}: ${response.statusText}`)
    }
    
    const content = await response.text()
    markdownContent.value = content
    await renderMarkdown()
  } catch (err:any) {
    console.error('加载 Markdown 文件失败:', err)
    error.value = err.message || '加载失败'
  } finally {
    loading.value = false
  }
}

const scrollToHeading = (headingId: string) => {
  if (!contentRef.value) return
  
  const targetElement = contentRef.value.querySelector(`#${headingId}`)
  if (targetElement) {
    // 找到主内容区域的滚动容器
    const scrollContainer = targetElement.closest('.overflow-y-auto')
    if (scrollContainer) {
      // 计算目标元素相对于滚动容器的位置
      const containerRect = scrollContainer.getBoundingClientRect()
      const targetRect = targetElement.getBoundingClientRect()
      const scrollTop = scrollContainer.scrollTop + (targetRect.top - containerRect.top) - 20 // 20px 偏移量
      
      // 在滚动容器内平滑滚动
      scrollContainer.scrollTo({
        top: scrollTop,
        behavior: 'smooth'
      })
    } else {
      // 如果没有找到滚动容器，使用默认的滚动方式
      targetElement.scrollIntoView({ behavior: 'smooth', block: 'start' })
    }
    activeHeading.value = headingId
  }
}

const handleScroll = () => {
  if (!contentRef.value) return
  
  const headings = contentRef.value.querySelectorAll('h1, h2, h3, h4, h5, h6')
  const scrollTop = contentRef.value.scrollTop
  
  let currentHeading = ''
  
  headings.forEach(heading => {
    const rect = heading.getBoundingClientRect()
    const containerRect = contentRef.value!.getBoundingClientRect()
    
    if (rect.top - containerRect.top <= 100) {
      currentHeading = heading.id
    }
  })
  
  activeHeading.value = currentHeading
}

// 监听 markdownContent 变化
watch(markdownContent, async () => {
  await renderMarkdown()
})

// 监听文件路径变化
watch(() => props.filePath, () => {
  if (isExpanded.value) {
    markdownContent.value = ''
    loadMarkdown()
  }
})
</script>

<style scoped>
.markdown-viewer {
  @apply w-full;
}

/* 自定义滚动条 */
.overflow-y-auto::-webkit-scrollbar {
  width: 6px;
}

.overflow-y-auto::-webkit-scrollbar-track {
  background: #f1f1f1;
}

.overflow-y-auto::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 3px;
}

.overflow-y-auto::-webkit-scrollbar-thumb:hover {
  background: #a1a1a1;
}

/* Prose 样式覆盖 */
:deep(.prose) {
  max-width: none;
}

:deep(.prose h1) {
  @apply text-2xl font-bold text-gray-900 mt-6 mb-4 pb-2 border-b border-gray-200;
}

:deep(.prose h2) {
  @apply text-xl font-semibold text-gray-800 mt-5 mb-3;
}

:deep(.prose h3) {
  @apply text-lg font-medium text-gray-800 mt-4 mb-2;
}

:deep(.prose h4) {
  @apply text-base font-medium text-gray-700 mt-3 mb-2;
}

:deep(.prose p) {
  @apply text-gray-600 leading-relaxed mb-3;
}

:deep(.prose ul) {
  @apply list-disc list-inside space-y-1 mb-4;
}

:deep(.prose ol) {
  @apply list-decimal list-inside space-y-1 mb-4;
}

:deep(.prose li) {
  @apply text-gray-600;
}

:deep(.prose code) {
  @apply bg-gray-100 px-1 py-0.5 rounded text-sm font-mono text-gray-800;
}

:deep(.prose blockquote) {
  @apply border-l-4 border-blue-500 pl-4 italic text-gray-600 bg-blue-50 py-2 my-4;
}

:deep(.prose table) {
  @apply w-full border-collapse border border-gray-300 my-4;
}

:deep(.prose th) {
  @apply bg-gray-100 border border-gray-300 px-3 py-2 text-left font-semibold;
}

:deep(.prose td) {
  @apply border border-gray-300 px-3 py-2;
}
</style>